#ifndef __LYNX_AUDIO_MANAGER_C_HPP_INCLUDED__
#define __LYNX_AUDIO_MANAGER_C_HPP_INCLUDED__

#include "LynxAudioManager.hpp"
#include "LynxLogManager.hpp"
#include "LynxException_C.hpp"
#include <AL/al.h>
#include <AL/alc.h>
#include <list>

namespace Lynx
{
namespace Audio
{

class AudioManager_C : public AudioManager
{
public:
    ////////////////////////////////////////////////////////////////////////////
    AudioManager_C(LogManager *manager);


    ////////////////////////////////////////////////////////////////////////////
    virtual ~AudioManager_C();


    ////////////////////////////////////////////////////////////////////////////
    virtual bool is_manager_active(void) const;


    ////////////////////////////////////////////////////////////////////////////
    virtual bool activate_manager(const char *device_name = 0);


    ////////////////////////////////////////////////////////////////////////////
    virtual void deactivate_manager(void);


    ////////////////////////////////////////////////////////////////////////////
    virtual std::string get_manager_name(void) const;


    ////////////////////////////////////////////////////////////////////////////
    virtual std::vector<std::string> get_possible_device_names(void) const;


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *create_static_source(Myth::Stream::Input *input, const std::string &name);


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *create_streaming_source(Myth::Stream::Input *input, const std::string &name);


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *create_debug_mono_source(const std::string &name);


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *create_debug_stereo_source(const std::string &name);


    ////////////////////////////////////////////////////////////////////////////
    virtual uint32_t get_source_amount(void) const;


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *get_source(uint32_t index) const;


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *get_source(const std::string &name) const;


    ////////////////////////////////////////////////////////////////////////////
    virtual bool remove_source(uint32_t index);


    ////////////////////////////////////////////////////////////////////////////
    virtual bool remove_source(const std::string &name);


    ////////////////////////////////////////////////////////////////////////////
    virtual bool remove_all_sources(void);


    ////////////////////////////////////////////////////////////////////////////
    virtual Sound *create_sound(SoundSource *source, bool play_looped = false, bool start_paused = false);


    ////////////////////////////////////////////////////////////////////////////
    virtual Sound *create_sound(SoundSource *source, Myth::Math::Vector3f pos, bool play_looped = false, bool start_paused = false);


    ////////////////////////////////////////////////////////////////////////////
    virtual void play_all_sounds(void);


    ////////////////////////////////////////////////////////////////////////////
    virtual void pause_all_sounds(void);


    ////////////////////////////////////////////////////////////////////////////
    virtual void stop_all_sounds(void);


    ////////////////////////////////////////////////////////////////////////////
    virtual uint32_t get_sound_amount(void) const;


    ////////////////////////////////////////////////////////////////////////////
    virtual Sound *get_sound(uint32_t index) const;


    ////////////////////////////////////////////////////////////////////////////
    virtual bool remove_sound(uint32_t index);


    ////////////////////////////////////////////////////////////////////////////
    virtual bool remove_all_sounds(void);


    ////////////////////////////////////////////////////////////////////////////
    virtual void add_audio_reader_loader(AudioReaderLoader *loader);


    ////////////////////////////////////////////////////////////////////////////
    void internal_remove_source(SoundSource *source);

private:
    ////////////////////////////////////////////////////////////////////////////
    void shutdown_engine();

private:
    ALCdevice *mDevice;
    ALCcontext *mContext;
    LogManager *mLogManager;

    AudioReaderLoader *mDebugMonoLoader;
    AudioReaderLoader *mDebugStereoLoader;

    bool mActive;
    std::string mDeviceName;
    std::list<SoundSource*> mSources;
    std::list<Sound*> mSounds;
    std::list<AudioReaderLoader*> mLoaders;

    std::vector<std::string> mDevices;
};

} // namespace Audio
} // namespace Lynx

#endif // __LYNX_AUDIO_MANAGER_C_HPP_INCLUDED__

